const fs = require("fs")
const path = require("path")
const glob = require("glob")
const { listToObj } = require("./plugins/utils")
const { formatStr } = require("./utils/format")
const { generateZhDict, mergeDictBySettings } = require("./utils/generateDict")
const TFile = require("./core/TFile")
const TApi = require("./core/TApi")
const TDict = require("./core/TDict")
const Processes = require("./core/processes")
// 注意：现在改为绝对路径
let PUBLIC_PATH = path.resolve(__dirname, "../public")

function replaceMark(str, replaces) {
  str = str.split(path.sep).join("__")
  Object.keys(replaces).forEach((key) => {
    str = str.replace(key.replace("/", "__"), replaces[key])
  })

  return str.replace(/(.js|.vue)/gim, "")
}

function contentReplaceKey(content, i18nList) {
  const list = []
  i18nList.forEach((item) => {
    const key = formatStr(item)
    content = content.replace(item, key)
    list.push({
      key,
      content: item,
    })
  })
  return { list, content }
}

function handleWriteSettingsTranslate(settings, transList, lang) {
  const transMap = listToObj(transList)
  Object.keys(settings).forEach((key) => {
    const item = settings[key]
    item.forEach((iItem) => {
      const i18nKey = `${key}.${iItem.key}`
      if (transMap[i18nKey]) iItem[`baidu_${lang}`] = transMap[i18nKey]
    })
  })
}

class main {
  i18nContent = {}
  config = {}

  constructor(config) {
    const { basePath, filePaths, skipFiles } = config
    this.config = config
    this.tDict = new TDict({
      dictPath: config.dictPath,
    })

    this.tFile = new TFile({
      basePath,
      filePaths,
      skipFiles,
    })

    this.tApi = new TApi({
      from: config.from,
      to: config.to,
      appid: config.appid,
      token: config.token,
      qtime: config.qtime,
    })
  }

  scanDir() {
    const componentList = this.tFile.mapDir()
    return componentList
  }

  async start() {
    const i18nSettings = {}
    const i18nContent = {}
    //1、遍历需要翻译的文件夹，得到文件列表
    const componentList = this.scanDir()
    const lang = this.config.to
    //2、遍历需要翻译的文件
    componentList.map((filePath) => {
      //读取文件
      const content = fs.readFileSync(filePath, "utf8")
      //获取文件名，主要区分vue,js的不同处理
      const extname = path.extname(filePath).slice(1)
      //获取国际化的key值
      const key = replaceMark(filePath, this.config.keyReplace)
      //最重要,解析为AST,并替换中文key
      const file = Processes[extname]({
        content,
        filePath,
        key,
      })

      if (file.i18nList.length) {
        const data = {}
        file.i18nList.forEach((name) => {
          data[name] = ""
        })

        i18nContent[key] = data

        const { content: fileContent, list: settingList } = contentReplaceKey(file.content, file.i18nList)
        //如果是js结尾的文件 添加import i18n from '@/lang';
        if (path.extname(file.filePath) == ".js") {
          file.content = "import i18n from '@/lang'" + "\n" + fileContent
        } else {
          file.content = fileContent
        }

        i18nSettings[key] = settingList
      }
      //重新写入文件
      fs.writeFileSync(file.filePath, file.content)
    })

    //写入中文文件 zh.json
    this.tDict.writeLang("zh", generateZhDict(i18nSettings))

    const waitTranslateList = mergeDictBySettings(i18nSettings, this.tDict.exportSetingsByLang(lang), lang)
    const transList = await this.tApi.translateList(waitTranslateList, lang)
    handleWriteSettingsTranslate(i18nSettings, transList, lang)

    this.tDict.updateSettings(i18nSettings)
    this.tDict.updateLang(lang)
  }
}

module.exports = main
